package com.action;

import cn.hutool.core.util.HexUtil;
import com.annotation.Lock;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.bean.ResponseBean;
import com.card.CpuCard;
import com.pojo.Admin;
import com.pojo.Card;
import com.pojo.UserInfo;
import com.service.AdminService;
import com.service.CardService;
import com.service.CpuCardService;
import com.service.UserInfoService;
import com.util.IconUtil;
import com.util.JwtUtil;
import com.util.StringUtil;
import com.util.ValidateHelper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.web.bind.annotation.*;

import javax.imageio.ImageIO;
import javax.servlet.http.HttpServletRequest;
import java.io.FileInputStream;
import java.util.List;
import java.util.Map;

@RequestMapping("cpu_card")
@RestController
@CrossOrigin("*")
public class CpuCardAction {

    @Autowired
    private CpuCardService cpuCardService ;

    @Value("${upload.dir}")
    private String upload ;

    @Autowired
    @Qualifier("redisTemplate")
    private RedisTemplate redisTemplate;

    @Autowired
    private UserInfoService staffService;

    @Autowired
    private CardService cardService;

    @Autowired
    private AdminService adminService;

    /**
     * 外部认证
     * @param cid   卡片序列号
     * @param random
     * @param type 0 使用出厂密钥进行外部认证 1 根目录外部认证   2 1001目录外部认证  3 新卡默认外部认证  4 新卡重置后默认密钥外部认证
     * @return
     */
    @RequestMapping("certification")
    public ResponseBean certification(String cid , String random , Integer type){
        if(StringUtil.isNull(random)) {
            return ResponseBean.error("请生成随机数") ;
        }
        String res = cpuCardService.waiburenzheng(cid , random , type) ;
        return new ResponseBean(200 , "ok" , res) ;
    }

    /**
     * 设置目录密钥
     * @return
     */
    @RequestMapping("set_dir_miyao")
    public ResponseBean setDirMiyao(){
        return new ResponseBean(200 , "ok" , CpuCard.setDirMiyao(null , null)) ;
    }

    /**
     * 充值
     * @param info         圈存初始化信息
     * @return
     */
//    @RequestMapping("chongzhi")
//    public ResponseBean chongzhi(String info , Integer money){
//        return new ResponseBean(200 , "成功" , CpuCard.chongzhi(info , null , money)) ;
//    }

    /**
     * 消费
     * @param info
     * @param money
     * @return
     */
    @RequestMapping("xiaofei")
    public ResponseBean xiaofei(String info , String money){
        return new ResponseBean(200 , "成功" , CpuCard.xiaofei(info , null , money)) ;
    }

    /**
     * 开卡
     * type 0 老卡 1 新卡
     * @return
     */
    @RequestMapping("create_card")
    public ResponseBean createCard(String cid , String uid , String ast , String random, @RequestParam(required = false) String uuID, HttpServletRequest request , @RequestParam(defaultValue = "0") Integer type,
                                   @RequestHeader(value = "token" , required = false) String token) {
        if (uuID == null || redisTemplate.opsForValue().get("kk" + uuID) == null) {
            return new ResponseBean(600,1,"请勿重复提交！");
        }else {
            //redisTemplate.opsForValue().set("kk" + uuID, null);
            redisTemplate.delete("kk" + uuID);
        }
//        Map<String , String> map = new HashMap<>() ;
//        String root = CpuCard.mainDirMiyao(null , null) ;
//        String dir = CpuCard.dataDirMiyao(null , null) ;
//        String xf = CpuCard.xiaofeiMiyao(null , null) ;
//        String qc = CpuCard.quancunMiyao(null , null) ;
//        String tac = CpuCard.tacMiyao(null , null) ;
//        String pin = CpuCard.pinMiyao(null , null) ;
//        map.put("root" , root) ;
//        map.put("dir" , dir) ;
//        map.put("xf" , xf) ;
//        map.put("qc" , qc) ;
//        map.put("tac" , tac) ;
//        map.put("pin" , pin) ;
        String operId = "";
        String msg = adminService.verifyToken(token);
        if (StringUtil.isNotNull(msg)){
            return ResponseBean.error(msg);
        }
        String adminId = JwtUtil.getUsername(token);
        Admin admin = adminService.getById(adminId);
        if (null != admin) {
            operId = admin.getId();
        }
        Map map = null ;
        if(type == 0) {
            map = cpuCardService.createCard(cid , uid , ast , random, operId) ;
        }else {
            map = cpuCardService.createNewCard(cid , uid , ast , random, operId) ;
        }
        if(map == null) {
            return ResponseBean.error("开卡失败") ;
        }
        if (map != null && map.containsKey("error")) {
            return ResponseBean.error(map.get("error").toString());
        }
        return map == null ? ResponseBean.error("用户已办卡") : new ResponseBean(200 , "成功" , map) ;
    }

    /**
     * 损坏卡写卡
     * @return
     */
    @RequestMapping("writeFaildCard")
    public ResponseBean writeFaildCard(String uid , String cid , String ast , String random , @RequestParam(defaultValue = "0") Integer type) {
        Map map = null ;
        if(type == 0) {
            map = cpuCardService.writeFaildCard(cid , uid , ast , random) ;
        }else {
            map = cpuCardService.writeFaildNewCard(cid , uid , ast , random) ;
        }
        if(map == null) {
            return ResponseBean.error("写卡失败") ;
        }
        if (map != null && map.containsKey("error")) {
            return ResponseBean.error(map.get("error").toString());
        }
        return  new ResponseBean(200 , "成功" , map) ;
    }

    /**
     * 充值预处理指令
     * @param money
     * @return
     */
    @RequestMapping("chongzhi_prepare")
    @Lock(name = "cz_pre")
    public ResponseBean chongzhiPrepare(Integer money, String czUUID , String cid){
        if(StringUtil.isNull(czUUID)) {
            return new ResponseBean(600 , "请勿重复提交!" , "请勿重复提交!") ;
        }
        if (!czUUID.equals(redisTemplate.opsForValue().get("czPre" + czUUID))) {
            return new ResponseBean(600,1,"请勿重复提交！");
        }else {
            redisTemplate.opsForValue().set("czPre" + czUUID, "");
        }
        Map map = cpuCardService.chongzhiPrepare(cid , money) ;
        return map.get("msg") != null ? ResponseBean.error((String) map.get("msg")) : new ResponseBean(200 , "成功" , map) ;
    }

    /**
     * 充值
     * @param info
     * @param money
     * @return
     */
    @RequestMapping("chongzhi")
    @Lock(name = "cz_pre")
    public ResponseBean chongzhi(String info , Integer money , String uid, String czUUID){
        if (!czUUID.equals(redisTemplate.opsForValue().get("cz" + czUUID))) {
            return new ResponseBean(600,1,"请勿重复提交！");
        }else {
            redisTemplate.opsForValue().set("cz" + czUUID, "");
        }
//        String msg = cpuCardService.chongzhiBalance(info,money,uid);
//        if (StringUtil.isNull(msg)){
//            return ResponseBean.ok("充值成功");
//        }
//        return ResponseBean.error(msg);
        Map map = cpuCardService.chongzhi(info , money , uid) ;
        return map == null ? ResponseBean.error("用户不存在") : new ResponseBean(200 , "成功" , map) ;
    }

    /**
     * 获取用户信息
     * @param cid
     * @return
     */
    @RequestMapping("get_userinfo_by_card")
    public ResponseBean userinfoByCard(String cid){
        UserInfo staff = cpuCardService.userinfoByCard(cid) ;
        return staff == null ? ResponseBean.error("卡未绑定用户") : new ResponseBean(200 , "成功" , staff) ;
    }

    /**
     * 将卡信息写入数据库
     * @param cid
     * @return
     */
    @RequestMapping("insert")
    public ResponseBean insert(String cid){
        String res = cpuCardService.insert(cid) ;
        return res != null ? ResponseBean.error(res) : new ResponseBean(200 , "成功" , "") ;
    }

    /**
     * 根据会员号获取写文件命令
     * @param uid
     * @return
     */
    @RequestMapping("get_userinfo")
    public ResponseBean getUserinfo(String uid){
        if(StringUtil.isNull(uid)) {
            return ResponseBean.error("请选择用户") ;
        }
        UserInfo staff = cpuCardService.getById(uid) ;
        String iconPath = upload+staff.getPicture() ;
        String icon = "" ;
        String img = null ;
        String douhao = HexUtil.encodeHexStr(",".getBytes()) ;  // 分割符
        String end = HexUtil.encodeHexStr("\n".getBytes()) ;    // 结束符
        try{
            img = IconUtil.icon(ImageIO.read(new FileInputStream(iconPath)) , 0.9f , 1024*5) ;
            icon = HexUtil.encodeHexStr(img) ;
        }catch(Exception e) {
            return ResponseBean.error("用户头像未找到") ;
        }
        //icon+douhao +
        String data = icon+douhao +HexUtil.encodeHexStr(staff.getName().getBytes())+ douhao + HexUtil.encodeHexStr(staff.getBh().getBytes())+douhao +end ;
//        System.out.println(data);
        List<String> res = CpuCard.writeFile("1E" , data) ;
        return new ResponseBean(200 , "成功" , res) ;
    }

    /**
     * 清空卡结构
     * @param ast
     * @return
     */
    @RequestMapping("clear_card")
    public ResponseBean clearCard(String ast){
        if(StringUtil.isNull(ast)) {
            return ResponseBean.error("请上传复位信息") ;
        }
        String s = CpuCard.clearCard(null, ast);
        return new ResponseBean(200 , "成功" , s) ;
    }

    /**
     * 充值测试
     * @param cid
     * @param info
     * @return
     */
    @RequestMapping("chongzhi_test")
    public ResponseBean chongzhiTest(String cid , String info){
        Map<String , String> map = cpuCardService.chongzhiTest(cid , info) ;
        if(map.get("error") != null) {
            return ResponseBean.error(map.get("error")) ;
        }
        return new ResponseBean(200 , "成功" , map.get("res")) ;
    }

    /**
     * 消费测试
     * @param cid
     * @param info
     * @return
     */
    @RequestMapping("xiaofei_test")
    public ResponseBean xiaofeiTest(String cid , String info){
        Map<String , String> map = cpuCardService.xiaofeiTest(cid , info) ;
        if(map.get("error") != null) {
            return ResponseBean.error(map.get("error")) ;
        }
        return new ResponseBean(200 , "成功" , map.get("res")) ;
    }

    /**
     * 擦除卡
     * @return
     */
    @RequestMapping("clearNewCard")
    public ResponseBean clearNewCard (String cardNo) {
        if (ValidateHelper.isEmptyString(cardNo)) {
            return ResponseBean.error("卡号为空");
        }

        UserInfo staff = staffService.getStaffByCardNo(cardNo);
        if (null == staff) {
            return ResponseBean.error("卡绑定的会员不存在");
        }

        Card card = cardService.getCardByCardNo(cardNo);
        if (null == card) {
            return ResponseBean.error("该卡没有绑定会员");
        }

        // 解除卡与会员绑定关系
        UpdateWrapper update = new UpdateWrapper();
        update.eq("id", staff.getId());
        update.set("card_no", null);
        update.set("pin", null);
        staffService.update(update);

        //删除卡表记录
        cardService.removeById(card.getId());

        return ResponseBean.ok("擦除成功！");
    }

    /**
     * 擦除卡
     * @return
     */
    @RequestMapping("clearNewCard1")
    public ResponseBean clearNewCard1 (String cardNo) {
        if (ValidateHelper.isEmptyString(cardNo)) {
            return ResponseBean.error("卡号为空");
        }

        Card card = cardService.getCardByCardNo(cardNo);
        if (null == card) {
            return ResponseBean.error("该卡没有绑定会员");
        }

        //删除卡表记录
        cardService.removeById(card.getId());

        return ResponseBean.ok("擦除成功！");
    }
}